/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <几何数据.h>
#include <数据工具库.h>
#include <mutex>

#include "引擎枚举数据.h"
#include "引擎数据类型.h"
#include "结构数据.h"

#include "shader_line.h"
#include "shader_ray.h"
#include "shader_std.h"


typedef void(*fp_GPU_BufferUpdate)(struct S_板载缓存* buf);

struct S_板载缓存 {
	void*          m_mappedPtr;
	//uint8*         m_mappedPtr;
	uint32	       m_Size;
	uint32	       m_Offset;
	uint64	       elt_capacity;


	S_设备环境     m_Ctx;
			       
	S_内存分配     m_分配器;
	//volatile int32 m_分配内存锁;
	std::mutex m_分配内存锁;
	std::mutex m_分配块内存锁;


	E_板载缓存类型      m_Type;
	fp_GPU_BufferUpdate m_Update;

	virtual E_vec3元素指针	f_getData() { return {0,0}; };
	virtual void			f_fillData(const void* data, uint64 bitSize) = 0;

	virtual void	f_map()		= 0;
	virtual void	f_unmap()	= 0;

	virtual void	f_resize(uint64 bitSize) = 0;
	virtual void	f_copy(S_结构对象指针 sObj) = 0;
	virtual void	f_change板载缓存(E_板载缓存类型 memType) = 0;
	virtual void	f_insert(uint64 offset, void* data, uint64 size) {}

	S_板载缓存() {
		m_mappedPtr = nullptr;
		m_Update    = nullptr;

		m_Size       = 0;
		m_Offset     = 0;
		elt_capacity = 0;

		m_分配器.maxNum = 0;
		//m_分配内存锁 = 1;
		//m_分配器.m_Data = (uint8*)malloc(1);
	}
	virtual ~S_板载缓存() {};
};


typedef struct {
	S_板载缓存**	m_Grup;
	uint32			m_Num;
}S_板载缓存组;




typedef struct {
	S_板载缓存*		m_视图矩阵;
	S_结构对象指针	m_GPU参数;
	S_结构对象指针	m_2D笔刷;
}S_2D绘制GPU全局参数;





/*#ifdef _DEBUG  

S_板载缓存* f_buf_create板载缓存(S_设备环境 ctx, uint16 offset, E_板载缓存类型 type = E_板载缓存类型::e_VBO, uint64 size = 0, const std::string fileName = (__FILE__), uint32 行号 = __LINE__);
S_板载缓存* f_buf_create板载缓存(S_设备环境 ctx, E_板载缓存类型 type, uint32 typeflags, uint16 offset, uint64 size, const std::string fileName = (__FILE__), uint32 行号 = __LINE__);
S_板载缓存* f_buf_create板载缓存(S_设备环境 ctx, E_板载缓存类型 type, uint16 offset, const std::string fileName = (__FILE__), uint32 行号 = __LINE__);

#else



#endif*/

S_板载缓存* f_buf_create板载缓存(S_设备环境 ctx, uint16 offset, E_板载缓存类型 type = E_板载缓存类型::e_VBO, uint64 size = 0);
S_板载缓存* f_buf_create板载缓存(S_设备环境 ctx, E_板载缓存类型 type, uint32 typeflags, uint16 offset, uint64 size);
S_板载缓存* f_buf_create板载缓存(S_设备环境 ctx, E_板载缓存类型 type, uint16 offset);


void		f_buf_release板载缓存(S_板载缓存* obj);
void        f_buf_释放所有();

uint32 f_getAPI缓存类型(E_板载缓存类型 memType);
uint32 f_getAPI光追加速缓存类型(E_板载缓存类型 memType);
uint32 f_get缓存布局类型(E_板载缓存类型 memType);

void f_fill板载缓存(S_板载缓存* obj, const std::vector<vec3>& data, E_板载缓存类型 memType, S_设备环境& ctx);
void f_fill板载缓存(S_板载缓存* obj, const std::vector<uint32>& data, E_板载缓存类型 memType, S_设备环境& ctx);

void f_fill板载缓存(S_板载缓存* obj, const std::vector<Mat44f>& data, E_板载缓存类型 memType, S_设备环境& ctx);

void f_fill板载缓存(S_板载缓存* obj, const Mat44f* data, uint64 offset);
void f_buf_set(S_板载缓存* obj, int8 val);
void f_buf_fill(S_板载缓存* obj, const void* val, uint64 num);



void f_buf_resize(S_板载缓存* obj, uint32 size);
void f_buf_erase(S_板载缓存* obj, uint32 loc, uint32 num = 1);
bool f_resize板载缓存_Up(S_板载缓存* obj, uint64 size);
void f_change板载缓存(S_板载缓存* obj, E_板载缓存类型 memType);




Inline void f_buf_fill板载缓存(S_板载缓存* obj, const void* data, uint64 count) {
	obj->m_Size = count;
	obj->f_fillData(data, obj->m_Size * obj->m_Offset);
}

template<typename T>
void f_buf_fill板载缓存(S_板载缓存* obj, const std::vector<T>& data, E_板载缓存类型 memType) {
	obj->m_Size = data.size();
	obj->m_Offset = sizeof(T);
	obj->m_Type = memType;
	obj->f_fillData(data.data(), data.size() * sizeof(T));
}

template<typename T>
void f_buf_fill板载缓存(S_板载缓存* obj, const std::vector<T>& data) {
	obj->m_Size = data.size();
	obj->m_Offset = sizeof(T);
	obj->f_fillData(data.data(), obj->m_Size * obj->m_Offset);
}


template<typename T>
void f_buf_fill板载缓存(S_板载缓存* obj, const T* data, uint64 num, E_板载缓存类型 memType) {
	obj->m_Size = num;
	obj->m_Type = memType;
	obj->f_fillData(data, num * obj->m_Offset);
}



Inline void f_buf_fill板载缓存(S_板载缓存* obj, uint16 bitSize, uint64 num, const void* data, E_板载缓存类型 memType) {
	obj->m_Size = num;
	obj->m_Type = memType;
	obj->m_Offset = bitSize;
	obj->f_fillData(data, num * obj->m_Offset);
}


Inline void f_buf_fill(S_板载缓存* obj, uint64 offset, const void* data, uint64 num) {
	obj->f_map();
	memcpy(&(((uint8*)obj->m_mappedPtr)[offset]), data, num);
	obj->f_unmap();
}

//注意一般情况下不要填指针类型
template<typename T>
void f_buf_set(S_板载缓存* obj, uint64 offset, const T& data) {
	obj->f_map();
	((T*)(obj->m_mappedPtr))[offset] = data;
	obj->f_unmap();
}

template<typename T>
void f_copy板载缓存array(S_板载缓存* obj, const T* data, uint64 count) {
	obj->f_map();
	//for (uint64 i=0; i < count; ++i) {
	//	((T*)(obj->m_mappedPtr))[i] = data[i];
	//}
	memcpy(obj->m_mappedPtr, data, sizeof(T) * count);
	obj->f_unmap();
}

template<typename T>
void f_copy板载缓存array(S_板载缓存* obj, uint64 offset, const T* data, uint64 count) {
	obj->f_map();
	memcpy(&(((T*)obj->m_mappedPtr)[offset]), data, sizeof(T) * count);
	obj->f_unmap();
}


Inline void f_buf_copy板载缓存(S_板载缓存* b1, S_板载缓存* b2) {
	uint64 num = b2->m_Size;
	b1->m_Offset = b2->m_Offset;

	f_buf_resize(b1, num);

	b1->f_map();
	b2->f_map();
	//for (uint64 i = 0; i < num * b1->m_Offset; ++i) {
	//	((uint8*)b1->m_mappedPtr)[i] = ((uint8*)b2->m_mappedPtr)[i];
	//}
	memcpy(b1->m_mappedPtr, b2->m_mappedPtr, num * b1->m_Offset);
	b1->f_unmap();
	b2->f_unmap();
}

Inline void f_buf_copy板载缓存(S_板载缓存* b1, void* b2) {
	b1->f_map();
	memcpy(b1->m_mappedPtr, b2, b1->m_Size * b1->m_Offset);
	b1->f_unmap();
}



template<typename T>
inline T* f_buf_map板载缓存(S_结构对象指针 obj) {
	((S_板载缓存*)obj)->f_map();
	return (T*)(((S_板载缓存*)obj)->m_mappedPtr);
}
template<typename T>
inline T* f_buf_map板载缓存(S_板载缓存* obj) {
	(obj)->f_map();
	return (T*)(obj->m_mappedPtr);
}


inline void f_buf_unmap板载缓存(S_结构对象指针 obj) {
	((S_板载缓存*)obj)->f_unmap();
}
inline void f_buf_unmap板载缓存(S_板载缓存* obj) {
	obj->f_unmap();
}





template<typename T>
void f_buf_append板载缓存(S_板载缓存* obj, const T& data) {
	f_buf_resize(obj, obj->m_Size + 1);

	obj->f_map();
	((T*)obj->m_mappedPtr)[obj->m_Size-1] = data;
	obj->f_unmap();
}

template<typename T>
void f_buf_push_back(S_板载缓存* obj, const std::vector<T>& data) {
	uint64 i = obj->m_Size;
	if (!data.size()) return;

	f_buf_resize(obj, obj->m_Size + data.size());
	
	obj->f_map();
	const T* p = data.data();
	memcpy((void*)&(((T*)obj->m_mappedPtr)[i]), p, data.size() * sizeof(T));
	obj->f_unmap();
}



template<typename T>
uint64 f_板载缓存_remove(S_板载缓存* obj, uint64 offset) {
	((T*)obj->m_mappedPtr)[offset] = ((T*)obj->m_mappedPtr)[obj->m_Size-1];
	--obj->m_Size;
	return obj->m_Size;
}


template<typename T>
uint64 f_板载缓存_remove(S_板载缓存* obj, uint32* id, uint32 num) {
	if (obj->m_Size <= 1) {
		obj->m_Size = 0;
		return 0;
	}
	uint32 末尾ID = obj->m_Size;
	auto 删除部件 = f_DT_末尾删除法移除数据<T>((T*)obj->m_mappedPtr, 末尾ID, id, num);
	obj->m_Size = 末尾ID;
	return obj->m_Size;
}


template<typename T>
uint64 f_板载缓存_remove段_swapEnd(S_板载缓存* obj, uint32 offset, uint32 num) {
	if (obj->m_Size <= num) {
		obj->m_Size = 0;
		return 0;
	}
	uint32 末尾ID = obj->m_Size - num;


	T* data = (T*)obj->m_mappedPtr;
	memcpy(&data[offset], &data[末尾ID], num * sizeof(T));
	
	obj->m_Size = 末尾ID;
	return obj->m_Size;
}

template<typename T>
uint64 f_buf_remove段_swapEnd(S_板载缓存* obj, uint32* id, uint64 num, uint64 offset) {
	if (obj->m_Size <= offset) {
		obj->m_Size = 0;
		return 0;
	}
	uint64 末尾ID = obj->m_Size;
	f_DT_末尾删除法移除数据组<T>((T*)obj->m_mappedPtr, 末尾ID, id, num, offset);
	obj->m_Size = 末尾ID * offset;
	return obj->m_Size;
}

inline void f_板载缓存_pop(S_板载缓存* obj, uint64 num) {
	obj->m_Size -= num;
}

Inline uint8* f_buf_at(S_板载缓存* buf, uint32 ID, uint32 offset) {
	return &((uint8*)buf->m_mappedPtr)[ID * offset];
}

void f_popend板载缓存(S_板载缓存* obj, int64 id=-1);

void f_clear板载缓存(S_板载缓存* obj);

void f_buf_insert(S_板载缓存* obj, int64 offset, const void* data, uint32 size);

uint64 f_buf_getAddress(S_板载缓存* buf);







//------------------------------ 全局统一分配内存 -------------------------------------------


S_GPU偏移大小 f_buf_galloc(S_板载缓存* buf, uint32 num);
void          f_buf_gfree(S_板载缓存* buf, S_GPU偏移大小& 块);
void          f_buf_gresize(S_GPU内存块索引& 块, uint32 newSize);
//void          f_buf_gresize(S_GPU内存块索引& 块, uint32 newSize, uint32 offset);


Inline S_GPU内存块索引 f_buf_alloc(S_板载缓存* buf, uint32 num) {
	if (num) {
		return {buf, f_buf_galloc(buf, num), nullptr, nullptr};
	}
	else {
		return {buf, {}, nullptr, nullptr };
	}
}
//Inline void f_buf_free(S_GPU内存块索引& 块) {
//	f_buf_gfree(块.m_Buf, 块.m_Mem);
//	块.m_Mem = {};
//}


Inline void f_buf_erase(S_GPU内存块索引& 块) {
	if (块.m_Mem.m_大小) {
		f_buf_gfree(块.m_Buf, 块.m_Mem);
		块.m_Mem = {};
		//块 = {};
	}
}

Inline void f_buf_erase(S_GPU内存块索引& 块, uint32 开始偏移, uint32 数量 = 1) {
	if (块.m_Mem.m_大小) {
		S_GPU内存块索引 新块 = f_buf_alloc(块.m_Buf, 块.m_Mem.m_大小 - 数量);

		uint8* scr = &(((uint8*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 * 块.m_Buf->m_Offset]);
		uint8* dst = &(((uint8*)新块.m_Buf->m_mappedPtr)[新块.m_Mem.m_偏移 * 新块.m_Buf->m_Offset]);

		memcpy(dst, scr, 开始偏移 * 块.m_Buf->m_Offset);

		dst = &dst[开始偏移 * 块.m_Buf->m_Offset];
		scr = &scr[(开始偏移 + 数量) * 块.m_Buf->m_Offset];
		memcpy(dst, scr, (块.m_Mem.m_大小 - (开始偏移 + 数量)) * 块.m_Buf->m_Offset);

		f_buf_gfree(块.m_Buf, 块.m_Mem);
		块 = 新块;
	}
}

Inline void f_gbuf_fill(S_GPU内存块索引& 块, const void* src, uint32 指针偏移, uint32 size) {
	f_buf_gresize(块, size);
	uint8* dst = &(((uint8*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 * 块.m_Buf->m_Offset + 指针偏移 * 块.m_Buf->m_Offset]);
	memcpy(dst, src, size * 块.m_Buf->m_Offset);
}

Inline void f_buf_down(const S_GPU内存块索引& 块, S_Array* dst) {
	f_core_array_resize(dst, 块.m_Mem.m_大小);
	uint8* src = &(((uint8*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 * 块.m_Buf->m_Offset]);
	memcpy(dst->ptr_userData, src, 块.m_Mem.m_大小 * 块.m_Buf->m_Offset);
}


Inline void f_buf_copy(S_GPU内存块索引& dst块, const S_GPU内存块索引& src块) {
	uint64 num = src块.m_Mem.m_大小;
	assert(dst块.m_Buf->m_Offset == src块.m_Buf->m_Offset);
	dst块.m_Buf->m_Offset = src块.m_Buf->m_Offset;

	f_buf_gresize(dst块, num);
	uint8* dst = &(((uint8*)dst块.m_Buf->m_mappedPtr)[dst块.m_Mem.m_偏移 * dst块.m_Buf->m_Offset]);
	uint8* src = &(((uint8*)dst块.m_Buf->m_mappedPtr)[src块.m_Mem.m_偏移 * src块.m_Buf->m_Offset]);
	memcpy(dst, src, num * dst块.m_Buf->m_Offset);
}


Inline uint32 f_buf_offset(const S_GPU内存块索引& 块) {
	return 块.m_Mem.m_偏移;
}

Inline float32& f_buf_F32_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_大小);
	return (((float32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline float32* f_buf_F32_ptr(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_大小);
	return &(((float32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}

Inline int32& f_buf_I32_at(const S_GPU内存块索引& 块, uint32 offset) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_大小);
	return (((int32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline int32* f_buf_I32_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((int32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}
Inline uint32& f_buf_UI32_at(const S_GPU内存块索引& 块, uint32 offset) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_大小);
	return (((uint32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline uint32* f_buf_UI32_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((uint32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}

Inline vec2& f_buf_Vec2_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((vec2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline vec2* f_buf_Vec2_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((vec2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}


Inline uvec2& f_buf_uVec2_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((uvec2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline uvec2* f_buf_uVec2_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((uvec2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}


Inline vec3& f_buf_Vec3_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((vec3*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline vec3* f_buf_Vec3_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((vec3*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}

Inline vec4& f_buf_Vec4_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((vec4*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline vec4* f_buf_Vec4_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((vec4*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}

Inline S_VN* f_buf_VN_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((S_VN*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}
Inline S_VC* f_buf_VC_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((S_VC*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}
Inline S_VNT1* f_buf_VNT_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((S_VNT1*)(块.m_Buf->m_mappedPtr))[块.m_Mem.m_偏移]);
}


Inline Mat44f& f_buf_Mat44_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_大小);
	return ((Mat44f*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline Mat44f* f_buf_Mat44_ptr(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_大小);
	return &(((Mat44f*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}

Inline mat3X2* f_buf_Mat3X2_ptr(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_大小);
	return &(((mat3X2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline mat3X2& f_buf_Mat3X2_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_大小);
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_大小);
	return (((mat3X2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}


Inline S_2D图元顶点& f_buf_图元顶点_at(const S_GPU内存块索引& 块, uint32 offset) {
	assert(offset < 块.m_Mem.m_大小);
	return (((S_2D图元顶点*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_2D图元顶点* f_buf_图元顶点_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((S_2D图元顶点*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}

Inline S_TextueProp& f_buf_纹理属性_at(const S_GPU内存块索引& 块, uint32 offset) {
	assert(offset < 块.m_Mem.m_大小);
	return (((S_TextueProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_TextueProp* f_buf_纹理属性_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((S_TextueProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}


Inline S_LineProp* f_buf_线属性_ptr(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_大小);
	return &(((S_LineProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_LineProp& f_buf_线属性_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_大小);
	return (((S_LineProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}


Inline S_ColorGradient& f_buf_渐变属性_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_大小);
	return (((S_ColorGradient*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_ColorGradient* f_buf_渐变属性_ptr(const S_GPU内存块索引& 块) {
	return &(((S_ColorGradient*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}


Inline S_VkDrawIndirectCommand& f_buf_at_Indirect(const S_GPU内存块索引& 块, uint32 offset) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_大小);
	return ((S_VkDrawIndirectCommand*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline S_VkDrawIndirectCommand* f_buf_Indirect_ptr(const S_GPU内存块索引& 块) {
	assert(块.m_Mem.m_大小);
	return &(((S_VkDrawIndirectCommand*)(块.m_Buf->m_mappedPtr))[块.m_Mem.m_偏移]);
}

Inline S_VkDrawIndexedIndirectCommand& f_buf_at_IndexIndirect(const S_GPU内存块索引& 块, uint32 offset) {
	assert(offset < 块.m_Mem.m_大小);
	assert(块.m_Mem.m_大小);
	return ((S_VkDrawIndexedIndirectCommand*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}



Inline S_MeshTranformProp* f_buf_物体变换属性_ptr(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_大小);
	return &(((S_MeshTranformProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_MeshTranformProp& f_buf_物体变换属性_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_大小);
	return (((S_MeshTranformProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}



Inline S_FaceElement* f_buf_面元素_ptr(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_大小);
	return &(((S_FaceElement*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_FaceElement& f_buf_面元素_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_大小);
	return (((S_FaceElement*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}


Inline S_ObMesh* f_buf_网格引用_ptr(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_大小);
	return &(((S_ObMesh*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_ObMesh& f_buf_网格引用_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_大小);
	return (((S_ObMesh*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}




Inline S_CurvePoint* f_buf_曲线段_ptr(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_大小);
	return &(((S_CurvePoint*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_CurvePoint& f_buf_曲线段_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_大小);
	return (((S_CurvePoint*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}






template<typename T>
void f_buf_push_back(S_GPU内存块索引& obj, const std::vector<T>& data) {
	uint64 i = obj.m_Mem.m_大小;
	if (!data.size()) return;

	f_buf_gresize(obj, i+data.size());

	const T* p = data.data();
	uint8* Dst = &(((uint8*)(obj.m_Buf->m_mappedPtr))[(obj.m_Mem.m_偏移+i)*obj.m_Buf->m_Offset]);
	memcpy(Dst, p, data.size() * sizeof(T));
}

Inline void f_buf_push_back(S_GPU内存块索引& obj, const uint8* data, uint32 num) {
	uint64 原数量 = obj.m_Mem.m_大小;
	if (!num) return;

	f_buf_gresize(obj, 原数量 + num);

	uint8* Dst = &( ((uint8*)(obj.m_Buf->m_mappedPtr))[ (obj.m_Mem.m_偏移 + 原数量) * obj.m_Buf->m_Offset ] );
	memcpy(Dst, data, num * obj.m_Buf->m_Offset);
}


template<typename T>
Inline T& f_buf_T元素_at(const S_GPU内存块索引& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_大小);
	return (((T*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}




void f_buf_刷新GPU内存(S_板载缓存* buf);
uint64 f_buf_getAddress(S_GPU内存块索引& 块);

//================================  工具扩展函数  ====================================

//void f_buf_resize(uint64 count, uint16 num, ...);





